/*************************************************
* Title：TinyToolKit
* Author：Opportunity 
* Describe：房间类
* CreateTime：2020-08-18 10:02:19
* Version：1.0
* Modify Recorder：
*************************************************/

using System;
using System.Collections.Generic;
using System.Linq;

namespace TinyToolKit.Network
{
    public class Room
    {
        //房间状态
        public enum Status
        {
            Prepare = 1, //准备中
            Fight = 2 //战斗中
        }

        public int roomId;
        public Status status;
        private int _maxPlayers;
        private Dictionary<string, Player> _players;
        public int CurPlayersCount => _players.Count;

        public Room(int maxPlayers)
        {
            status = Status.Prepare;
            _maxPlayers = maxPlayers;
            _players = new Dictionary<string, Player>();
        }

        public bool AddPlayer(Player player)
        {
            lock (_players)
            {
                if (_players.Count >= _maxPlayers)
                {
                    TLogTool.Info($"房间ID:{roomId}的人数已满，不能再加入新玩家");
                    return false;
                }

                if (_players.ContainsKey(player.id) == false)
                {
                    PlayerTempData tempData = player.tempData;
                    if (tempData.status == PlayerTempData.Status.Room)
                    {
                        TLogTool.Info($"玩家{player.id}已经加入过房间{tempData.room.roomId}了，不能重复加入其它房间");
                        return false;
                    }

                    tempData.room = this;
                    tempData.team = GetTeamNum();
                    tempData.status = PlayerTempData.Status.Room;
                    tempData.isOwner = false;
                    if (_players.Count == 0)
                        tempData.isOwner = true;

                    _players.Add(player.id, player);
                    return true;
                }
                else
                {
                    TLogTool.Info($"玩家{player.id}已经存在房间{roomId}内，不能重复加入同一个房间");
                    return false;
                }
            }
        }

        public bool RemovePlayer(string id)
        {
            lock (_players)
            {
                if (_players.ContainsKey(id) == false) return false;
                _players[id].tempData.status = PlayerTempData.Status.None;
                bool isOwner = _players[id].tempData.isOwner;
                _players[id].tempData.isOwner = false;
                _players.Remove(id);

                //如果移除的是房主，并且房间还有其他玩家，则需要重新选出房主
                if (isOwner && _players.Count > 0)
                    UpdateOwner();
                
                return true;
            }
        }

        //向玩家广播消息
        public void Broadcast(ProtocolBase protocol)
        {
            foreach (var player in _players.Values)
            {
                player.Send(protocol);
            }
        }

        //获取房间信息，协议名+玩家数量+玩家1的id+玩家1是否为房主+玩家2的id+玩家2是否为房主  
        public ProtocolBytes GetRoomInfo()
        {
            ProtocolBytes protocol = new ProtocolBytes();
            protocol.AddString(Enum.GetName(typeof(RequestType), RequestType.Room));
            protocol.AddString("GetRoomInfo");
            protocol.AddInt(roomId);
            protocol.AddInt(_players.Count);
            foreach (var player in _players.Values)
            {
                protocol.AddString(player.id);
                int isOwner = player.tempData.isOwner ? 1 : 0;
                protocol.AddInt(isOwner);
            }

            return protocol;
        }

        //判断房间能否可以开战
        //一判断房间是否处于准备状态，每个阵营是否至少有一名玩家
        public bool CanStart()
        {
            if (status != Status.Prepare) return false;

            int firstTeamPlayerCount = 0;
            int secondTeamPlayerCount = 0;

            return true;
        }

        //开始游戏,并广播玩家生成信息给房间内所有玩家
        public void StartGame()
        {
            ProtocolBytes protocol = new ProtocolBytes();
            protocol.AddString("Fight");
            status = Status.Fight;
        }

        //选区玩家列表里的第一位玩家作为房主
        private void UpdateOwner()
        {
            lock (_players)
            {
                if (_players.Count <= 0) return;

                foreach (var player in _players.Values)
                {
                    player.tempData.isOwner = false;
                }

                _players.Values.First().tempData.isOwner = true;
            }
        }

        //获取队伍Index
        private int GetTeamNum()
        {
            int count1 = 0;
            int count2 = 0;
            foreach (var player in _players.Values)
            {
                if (player.tempData.team == 1) count1++;
                if (player.tempData.team == 2) count2++;
            }

            if (count1 <= count2)
                return 1;
            else
                return 2;
        }
    }
}